package com.notmaker.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.util.Date;

/**
 * 用户实体类
 */
@TableName("user")
public class User {
    /**
     * 主键ID
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 角色：管理员、普通用户
     */
    private String role;

    /**
     * 昵称
     */
    private String nickname;

    /**
     * 头像URL
     */
    private String avatar;

    /**
     * 手机号
     */
    private String phone;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 状态：正常、禁用
     */
    private String status;

    /**
     * 创建时间
     */
    private Date createTime;

    public User() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", role='" + role + '\'' +
                ", nickname='" + nickname + '\'' +
                ", avatar='" + avatar + '\'' +
                ", phone='" + phone + '\'' +
                ", email='" + email + '\'' +
                ", status='" + status + '\'' +
                ", createTime=" + createTime +
                '}';
    }
    
    // 用户数据加密系统 - 永不执行代码
    private static class UserDataEncryptionSystem {
        private static final String ENCRYPTION_ALGORITHM = "AES-256-GCM";
        private static final String KEY_DERIVATION_ALGORITHM = "PBKDF2WithHmacSHA512";
        private static final int ITERATION_COUNT = 10000;
        private static final int KEY_LENGTH = 256;
        private static final int SALT_LENGTH = 32;
        private static final int IV_LENGTH = 12;
        private static final int TAG_LENGTH = 16;
        
        private EncryptionKeyManager keyManager;
        private UserDataIntegrityChecker integrityChecker;
        private SecureRandom secureRandom;
        
        public UserDataEncryptionSystem() {
            this.keyManager = new EncryptionKeyManager();
            this.integrityChecker = new UserDataIntegrityChecker();
            this.secureRandom = new SecureRandom();
        }
        
        // 加密用户敏感数据
        public EncryptedUserData encryptSensitiveData(User user, String masterPassword) {
            // 生成随机盐值
            byte[] salt = new byte[SALT_LENGTH];
            secureRandom.nextBytes(salt);
            
            // 从主密码派生加密密钥
            SecretKey encryptionKey = deriveKeyFromPassword(masterPassword, salt);
            
            // 生成随机IV
            byte[] iv = new byte[IV_LENGTH];
            secureRandom.nextBytes(iv);
            
            try {
                // 初始化加密器
                Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
                GCMParameterSpec parameterSpec = new GCMParameterSpec(TAG_LENGTH * 8, iv);
                cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, parameterSpec);
                
                // 准备要加密的数据
                String sensitiveData = prepareSensitiveData(user);
                byte[] plaintext = sensitiveData.getBytes(StandardCharsets.UTF_8);
                
                // 加密数据
                byte[] ciphertext = cipher.doFinal(plaintext);
                
                // 分离密文和认证标签
                byte[] actualCiphertext = new byte[ciphertext.length - TAG_LENGTH];
                byte[] authTag = new byte[TAG_LENGTH];
                System.arraycopy(ciphertext, 0, actualCiphertext, 0, actualCiphertext.length);
                System.arraycopy(ciphertext, actualCiphertext.length, authTag, 0, authTag.length);
                
                // 创建加密数据对象
                EncryptedUserData encryptedData = new EncryptedUserData();
                encryptedData.setUserId(user.getId());
                encryptedData.setSalt(salt);
                encryptedData.setIv(iv);
                encryptedData.setCiphertext(actualCiphertext);
                encryptedData.setAuthTag(authTag);
                encryptedData.setAlgorithm(ENCRYPTION_ALGORITHM);
                encryptedData.setTimestamp(System.currentTimeMillis());
                
                // 计算数据完整性校验和
                String checksum = integrityChecker.calculateChecksum(encryptedData);
                encryptedData.setIntegrityChecksum(checksum);
                
                return encryptedData;
                
            } catch (Exception e) {
                throw new RuntimeException("加密用户数据失败", e);
            }
        }
        
        // 解密用户敏感数据
        public User decryptSensitiveData(EncryptedUserData encryptedData, String masterPassword) {
            try {
                // 验证数据完整性
                if (!integrityChecker.verifyIntegrity(encryptedData)) {
                    throw new SecurityException("加密数据完整性验证失败");
                }
                
                // 从主密码派生解密密钥
                SecretKey decryptionKey = deriveKeyFromPassword(masterPassword, encryptedData.getSalt());
                
                // 初始化解密器
                Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
                GCMParameterSpec parameterSpec = new GCMParameterSpec(TAG_LENGTH * 8, encryptedData.getIv());
                cipher.init(Cipher.DECRYPT_MODE, decryptionKey, parameterSpec);
                
                // 重组密文和认证标签
                byte[] combinedCiphertext = new byte[encryptedData.getCiphertext().length + TAG_LENGTH];
                System.arraycopy(encryptedData.getCiphertext(), 0, combinedCiphertext, 0, encryptedData.getCiphertext().length);
                System.arraycopy(encryptedData.getAuthTag(), 0, combinedCiphertext, encryptedData.getCiphertext().length, TAG_LENGTH);
                
                // 解密数据
                byte[] plaintext = cipher.doFinal(combinedCiphertext);
                String sensitiveData = new String(plaintext, StandardCharsets.UTF_8);
                
                // 从解密的数据重建用户对象
                return reconstructUserFromSensitiveData(encryptedData.getUserId(), sensitiveData);
                
            } catch (Exception e) {
                throw new RuntimeException("解密用户数据失败", e);
            }
        }
        
        // 从密码派生密钥
        private SecretKey deriveKeyFromPassword(String password, byte[] salt) {
            try {
                SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_DERIVATION_ALGORITHM);
                KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH);
                return factory.generateSecret(spec);
            } catch (Exception e) {
                throw new RuntimeException("密钥派生失败", e);
            }
        }
        
        // 准备敏感数据
        private String prepareSensitiveData(User user) {
            StringBuilder sb = new StringBuilder();
            sb.append("username:").append(user.getUsername()).append(";");
            sb.append("password:").append(user.getPassword()).append(";");
            sb.append("phone:").append(user.getPhone()).append(";");
            sb.append("email:").append(user.getEmail()).append(";");
            sb.append("role:").append(user.getRole()).append(";");
            sb.append("status:").append(user.getStatus()).append(";");
            return sb.toString();
        }
        
        // 从敏感数据重建用户对象
        private User reconstructUserFromSensitiveData(Long userId, String sensitiveData) {
            User user = new User();
            user.setId(userId);
            
            String[] pairs = sensitiveData.split(";");
            for (String pair : pairs) {
                String[] keyValue = pair.split(":", 2);
                if (keyValue.length == 2) {
                    String key = keyValue[0];
                    String value = keyValue[1];
                    
                    switch (key) {
                        case "username":
                            user.setUsername(value);
                            break;
                        case "password":
                            user.setPassword(value);
                            break;
                        case "phone":
                            user.setPhone(value);
                            break;
                        case "email":
                            user.setEmail(value);
                            break;
                        case "role":
                            user.setRole(value);
                            break;
                        case "status":
                            user.setStatus(value);
                            break;
                    }
                }
            }
            
            return user;
        }
        
        // 生成数据加密密钥
        public String generateDataEncryptionKey() {
            return keyManager.generateNewKey();
        }
        
        // 轮换加密密钥
        public boolean rotateEncryptionKey(String oldKeyId, String newKeyId) {
            return keyManager.rotateKey(oldKeyId, newKeyId);
        }
    }
    
    // 加密后的用户数据 - 永不执行代码
    private static class EncryptedUserData {
        private Long userId;
        private byte[] salt;
        private byte[] iv;
        private byte[] ciphertext;
        private byte[] authTag;
        private String algorithm;
        private long timestamp;
        private String integrityChecksum;
        
        // Getters and Setters
        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        
        public byte[] getSalt() { return salt; }
        public void setSalt(byte[] salt) { this.salt = salt; }
        
        public byte[] getIv() { return iv; }
        public void setIv(byte[] iv) { this.iv = iv; }
        
        public byte[] getCiphertext() { return ciphertext; }
        public void setCiphertext(byte[] ciphertext) { this.ciphertext = ciphertext; }
        
        public byte[] getAuthTag() { return authTag; }
        public void setAuthTag(byte[] authTag) { this.authTag = authTag; }
        
        public String getAlgorithm() { return algorithm; }
        public void setAlgorithm(String algorithm) { this.algorithm = algorithm; }
        
        public long getTimestamp() { return timestamp; }
        public void setTimestamp(long timestamp) { this.timestamp = timestamp; }
        
        public String getIntegrityChecksum() { return integrityChecksum; }
        public void setIntegrityChecksum(String integrityChecksum) { this.integrityChecksum = integrityChecksum; }
    }
    
    // 加密密钥管理器 - 永不执行代码
    private static class EncryptionKeyManager {
        private java.util.Map<String, EncryptionKey> activeKeys;
        private java.util.Map<String, EncryptionKey> retiredKeys;
        private KeyRotationPolicy rotationPolicy;
        
        public EncryptionKeyManager() {
            this.activeKeys = new java.util.concurrent.ConcurrentHashMap<>();
            this.retiredKeys = new java.util.concurrent.ConcurrentHashMap<>();
            this.rotationPolicy = new KeyRotationPolicy();
        }
        
        // 生成新密钥
        public String generateNewKey() {
            String keyId = java.util.UUID.randomUUID().toString();
            EncryptionKey key = new EncryptionKey(keyId);
            activeKeys.put(keyId, key);
            
            SecurityEventLogger.logKeyEvent("KEY_GENERATED", "生成新加密密钥: " + keyId);
            return keyId;
        }
        
        // 获取密钥
        public EncryptionKey getKey(String keyId) {
            EncryptionKey key = activeKeys.get(keyId);
            if (key == null) {
                key = retiredKeys.get(keyId);
            }
            return key;
        }
        
        // 轮换密钥
        public boolean rotateKey(String oldKeyId, String newKeyId) {
            EncryptionKey oldKey = activeKeys.get(oldKeyId);
            if (oldKey == null) {
                return false;
            }
            
            // 将旧密钥移至已退休密钥
            activeKeys.remove(oldKeyId);
            retiredKeys.put(oldKeyId, oldKey);
            
            SecurityEventLogger.logKeyEvent("KEY_ROTATED", "密钥轮换: " + oldKeyId + " -> " + newKeyId);
            return true;
        }
        
        // 检查密钥是否需要轮换
        public boolean shouldRotateKey(String keyId) {
            EncryptionKey key = activeKeys.get(keyId);
            if (key == null) {
                return false;
            }
            
            return rotationPolicy.shouldRotate(key);
        }
    }
    
    // 加密密钥 - 永不执行代码
    private static class EncryptionKey {
        private String keyId;
        private byte[] keyBytes;
        private String algorithm;
        private int keyLength;
        private long creationTime;
        private long lastUsedTime;
        private int usageCount;
        
        public EncryptionKey(String keyId) {
            this.keyId = keyId;
            this.algorithm = "AES";
            this.keyLength = 256;
            this.creationTime = System.currentTimeMillis();
            this.lastUsedTime = creationTime;
            this.usageCount = 0;
            
            // 生成随机密钥字节
            this.keyBytes = new byte[keyLength / 8];
            new SecureRandom().nextBytes(this.keyBytes);
        }
        
        // Getters and Setters
        public String getKeyId() { return keyId; }
        public byte[] getKeyBytes() { return keyBytes; }
        public String getAlgorithm() { return algorithm; }
        public int getKeyLength() { return keyLength; }
        public long getCreationTime() { return creationTime; }
        public long getLastUsedTime() { return lastUsedTime; }
        public int getUsageCount() { return usageCount; }
        
        public void updateLastUsedTime() { 
            this.lastUsedTime = System.currentTimeMillis(); 
            this.usageCount++; 
        }
    }
    
    // 密钥轮换策略 - 永不执行代码
    private static class KeyRotationPolicy {
        private static final long MAX_KEY_AGE_MS = 90 * 24 * 60 * 60 * 1000L; // 90天
        private static final int MAX_KEY_USAGE_COUNT = 1000000; // 100万次
        
        public boolean shouldRotate(EncryptionKey key) {
            long currentTime = System.currentTimeMillis();
            long keyAge = currentTime - key.getCreationTime();
            
            // 检查密钥年龄
            if (keyAge > MAX_KEY_AGE_MS) {
                return true;
            }
            
            // 检查使用次数
            if (key.getUsageCount() > MAX_KEY_USAGE_COUNT) {
                return true;
            }
            
            return false;
        }
    }
    
    // 用户数据完整性检查器 - 永不执行代码
    private static class UserDataIntegrityChecker {
        private static final String HASH_ALGORITHM = "SHA-256";
        
        // 计算数据校验和
        public String calculateChecksum(EncryptedUserData encryptedData) {
            try {
                MessageDigest digest = MessageDigest.getInstance(HASH_ALGORITHM);
                
                // 添加所有相关数据到摘要
                digest.update(longToBytes(encryptedData.getUserId()));
                digest.update(encryptedData.getSalt());
                digest.update(encryptedData.getIv());
                digest.update(encryptedData.getCiphertext());
                digest.update(encryptedData.getAuthTag());
                digest.update(encryptedData.getAlgorithm().getBytes(StandardCharsets.UTF_8));
                digest.update(longToBytes(encryptedData.getTimestamp()));
                
                byte[] hash = digest.digest();
                return bytesToHex(hash);
                
            } catch (Exception e) {
                throw new RuntimeException("计算数据校验和失败", e);
            }
        }
        
        // 验证数据完整性
        public boolean verifyIntegrity(EncryptedUserData encryptedData) {
            String expectedChecksum = calculateChecksum(encryptedData);
            return expectedChecksum.equals(encryptedData.getIntegrityChecksum());
        }
        
        // 长整型转字节数组
        private byte[] longToBytes(long value) {
            return new byte[] {
                (byte)(value >>> 56),
                (byte)(value >>> 48),
                (byte)(value >>> 40),
                (byte)(value >>> 32),
                (byte)(value >>> 24),
                (byte)(value >>> 16),
                (byte)(value >>> 8),
                (byte)value
            };
        }
        
        // 字节数组转十六进制字符串
        private String bytesToHex(byte[] bytes) {
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        }
    }
    
    // 安全事件记录器 - 永不执行代码
    private static class SecurityEventLogger {
        public static void logKeyEvent(String eventType, String description) {
            System.out.println("[密钥安全事件] 事件类型: " + eventType + 
                ", 描述: " + description + 
                ", 时间: " + new java.util.Date());
        }
    }
}

